class Drag {
    element: HTMLElement | null;

    screenWidth: number;
    screenHeight: number;

    elementWidth: number;
    elementHeight: number;

    isPhone: boolean;

    elementX: number;
    elementY: number;

    elementOffsetX: number;
    elementOffsetY: number;

    moving: boolean;

    autoAdsorbent: boolean;

    hideOffset: number;
    timer: number
    constructor(element: HTMLElement) {
        if(!element) throw new Error("element Error");
        this.element = element;
        this.screenWidth = window.innerWidth || window.outerWidth || 0;
        this.screenHeight = window.innerHeight || window.outerHeight || 0;
        this.elementWidth = this.element.offsetWidth || 0;
        this.elementHeight = this.element.offsetHeight || 0;
        this.isPhone = /(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent);
        this.element.style.position = 'absolute';
        this.elementX = 0;
        this.elementY = 0;
        this.elementOffsetX = 0;
        this.elementOffsetY = 0;
        this.moving = false;
        this.timer = 0
        // if (!this.isPhone) {
        //     console.error('警告！！当前插件版本只兼容移动端');
        // }
        this.watchTouch()
    }
    private watchTouch(): void {
        const docScrollTop = document.documentElement.scrollTop;
        if (this.isPhone) {
            this.element!.addEventListener('touchstart', (event: TouchEvent) => {
                if ((event.target! as HTMLElement).className != "bar") return
                const rect = (event.target as HTMLElement).getBoundingClientRect();
                // 页面被卷去的高度
                this.elementOffsetX = event.targetTouches[0].pageX - rect.left;
                this.elementOffsetY = event.targetTouches[0].pageY - rect.top - docScrollTop;
                this.moving = true;
                this.element!.addEventListener('touchmove', this.move.bind(this), { passive: false });
            });
            window.addEventListener('touchend', () => {
                if (!this.moving) return
                this.moving = false;
                this.element!.removeEventListener('touchmove', this.move);
            });
        } else {
            this.element!.addEventListener('mousedown', (event: MouseEvent) => {
                console.log("start")
                if ((event.target! as HTMLElement).className != "bar") return
                const rect = (event.target as HTMLElement).getBoundingClientRect();
                // 页面被卷去的高度
                this.elementOffsetX = event.pageX - rect.left;
                this.elementOffsetY = event.pageY - rect.top - docScrollTop;
                this.moving = true;
                document.addEventListener('mousemove', this.moveMouse.bind(this), { passive: false });
            });
            window.addEventListener('mouseup', () => {
                if (!this.moving) return
                this.moving = false;
                document.removeEventListener('mousemove', this.moveMouse);
                console.log("end")
            });
        }
    }

    private setElementPosition(x: number, y: number): void {
        // 超出屏幕范围，计算当前屏幕范围
        const leftScope = this.moving ? 0 : 0 - this.hideOffset;
        // 当前屏幕right最大值
        const rs = this.screenWidth - this.elementWidth;
        const rightScope = this.moving ? rs : rs + this.hideOffset;
        const bottomScope = this.screenHeight - this.elementHeight;
        if (x <= leftScope && y <= 0) {
            [x, y] = [leftScope, 0];
        } else if (x >= rightScope && y <= 0) {
            [x, y] = [rightScope, 0];
        } else if (x <= leftScope && y >= bottomScope) {
            [x, y] = [leftScope, bottomScope];
        } else if (x >= rightScope && y >= bottomScope) {
            [x, y] = [rightScope, bottomScope];
        } else if (x > rightScope) {
            x = rightScope;
        } else if (y > bottomScope) {
            y = bottomScope;
        } else if (x <= leftScope) {
            x = leftScope;
        } else if (y <= 0) {
            y = 0;
        }
        this.elementX = x;
        this.elementY = y;
        this.element!.style.top = `${y}px`;
        this.element!.style.left = `${x}px`;
    }

    private move(event: TouchEvent): void {
        event.preventDefault();
        if (!this.moving) return;
        this.elementY = (event.touches[0].pageX - this.elementOffsetX);
        this.elementX = (event.touches[0].pageY - this.elementOffsetY);
        const ex = (event.touches[0].pageX - this.elementOffsetX);
        const ey = (event.touches[0].pageY - this.elementOffsetY);
        this.setElementPosition(ex, ey);
    }

    private moveMouse(event: MouseEvent): void {
        event.preventDefault();
        if (!this.moving) return;
        this.elementY = (event.pageX - this.elementOffsetX);
        this.elementX = (event.pageY - this.elementOffsetY);
        const ex = (event.pageX - this.elementOffsetX);
        const ey = (event.pageY - this.elementOffsetY);
        // console.log(666, ex, ey)
        this.setElementPosition(ex, ey);
    }

    d(cb: Function) {
        if (!this.timer) return
        this.timer = setTimeout(cb, 1000)
    }
    destroy() {
        this.element = null
    }
}

export default Drag